﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using PPI.Entities.XML;
using VMind.Global;
using PPI.Client.Utils;
namespace PPI.Controls.Grid
{
    /// <summary>
    /// GridBase provides base for every control that implements a grid in PPI (contains edit & delete events)
    /// </summary>
    public partial class GridBase : UserControl
    {
        /// <summary>
        /// Defines the column name that will be the the ID
        /// </summary>
        protected string m_ColumnId = "ID";
        private bool m_ShowContextMenu;
        protected EXmlOutboxBase m_OutboxBase;
        protected bool m_ActivateDoubleClick;

        #region Properties

        public bool ShowContextMenu
        {
            get { return m_ShowContextMenu; }
            set { m_ShowContextMenu = value; }
        }

        public EXmlOutboxBase OutboxBase
        {
            get { return m_OutboxBase; }
            set { m_OutboxBase = value; }
        }

        public bool ShowAssociateOption
        {
            set { cmiAssociateUtility.Visible = value; }
        }

        #endregion


        /// <summary>
        /// Returns the Datagrid object associated to the control
        /// </summary>
        public DataGridView Datagrid
        {
            get { return datagridBase; }
        }

        public GridBase()
        {
            InitializeComponent();
            datagridBase.AutoGenerateColumns = false;
            m_ShowContextMenu = true;
            m_ActivateDoubleClick = true;
        }

        #region Events

        #region GridBase

        public event EventHandler<GridBaseEventArgs> ClickLinkCell;
        public event EventHandler<GridBaseEventArgs> CellChanged;
        /// <summary>
        /// Event raised when the edit menu option is clicked
        /// </summary>
        public event EventHandler<GridBaseEventArgs> ClickedEdit;
        /// <summary>
        /// Event raised when the edit without images menu option is clicked
        /// </summary>
        public event EventHandler<GridBaseEventArgs> ClickedEditWithoutImages;
        /// <summary>
        /// Event raised when the delete menu option is clicked
        /// </summary>
        public event EventHandler<GridBaseEventArgs> ClickedDelete;
        /// <summary>
        /// Event raised when the associate menu option is clicked
        /// </summary>
        public event EventHandler<GridBaseEventArgs> ClickedAssociate;

        private void OnClickLinkCell(object o, GridBaseEventArgs e)
        {
            // Safely invoke an event:
            if (ClickLinkCell != null)
            {
                ClickLinkCell(o, e);
            }
        }
        private void OnCellChanged(object o, GridBaseEventArgs e)
        {
            // Safely invoke an event:
            if (CellChanged != null)
            {
                CellChanged(o, e);
            }
        }
        protected void OnClickedEdit(object o, GridBaseEventArgs e)
        {
            // Safely invoke an event:
            if (ClickedEdit != null)
            {
                ClickedEdit(o, e);
            }
        }
        private void OnClickedEditWithoutImages(object o, GridBaseEventArgs e)
        {
            // Safely invoke an event:
            if (ClickedEditWithoutImages != null)
            {
                ClickedEditWithoutImages(o, e);
            }
        }
        private void OnClickedDelete(object o, GridBaseEventArgs e)
        {
            // Safely invoke an event:
            if (ClickedDelete != null)
            {
                ClickedDelete(o, e);
            }
        }
        private void OnClickedAssociate(object o, GridBaseEventArgs e)
        {
            // Safely invoke an event:
            if (ClickedAssociate != null)
            {
                ClickedAssociate(o, e);
            }
        }
        void cmbMenu_PopupOpen(object sender, DevComponents.DotNetBar.PopupOpenEventArgs e)
        {
            AfterOpenMenu();
            e.Cancel = !m_ShowContextMenu;
        }
        #endregion

        #region Datagrid

        protected virtual void datagridBase_DoubleClick(object sender, EventArgs e)
        {
            if (m_ActivateDoubleClick)
                OnClickedEdit(this,new GridBaseEventArgs(getSelectedId(),datagridBase.SelectedRows[0]));
        }

        #endregion

        #region Menu

        private void cmiEdit_Click(object sender, EventArgs e)
        {
            if(getSelectedId() != Int32.MinValue)
                OnClickedEdit(this,new GridBaseEventArgs(getSelectedId(),datagridBase.SelectedRows[0]));
        }

        private void cmiDeleteAsset_Click(object sender, EventArgs e)
        {
            if (getSelectedId() != Int32.MinValue)
                OnClickedDelete(this, new GridBaseEventArgs(getSelectedId(), datagridBase.SelectedRows[0]));

        }

        private void cmiAssociateUtility_Click(object sender, EventArgs e)
        {
            if (getSelectedId() != Int32.MinValue)
                OnClickedAssociate(this, new GridBaseEventArgs(getSelectedId(), datagridBase.SelectedRows[0]));

        }

        private void cmiEditWhithOutImages_Click(object sender, EventArgs e)
        {
            if (getSelectedId() != Int32.MinValue)
                OnClickedEditWithoutImages(this, new GridBaseEventArgs(getSelectedId(), datagridBase.SelectedRows[0]));

        }

        #endregion

        #endregion

        #region Protected Methods

        /// <summary>
        /// Verifies if there is any row selected. If there is a selected row, returns the ID value. If there is no selected row returns INT32.minValue value.
        /// </summary>
        /// <returns></returns>
        protected Int32 getSelectedId()
        {
            //return Int32.MinValue;
            if (datagridBase.SelectedRows.Count > 0)
            {
                return ConvertHelper.ToInt32(((DataRowView)datagridBase.SelectedRows[0].DataBoundItem).Row[m_ColumnId]);
            }
            else
            {
                return Int32.MinValue;
            }
        }

        protected DataRowView getSelectedRow()
        {
            //return null;
            if (datagridBase.SelectedRows.Count > 0)
            {
                return (DataRowView)datagridBase.SelectedRows[0].DataBoundItem;
            }
            else
            {
                return null;
            }
        }

        #endregion

        #region Public Methods
        
        /// <summary>
        /// Removes the datagrid row passed as parameter
        /// </summary>
        /// <param name="drv"></param>
        public void RemoveRow(DataGridViewRow drv)
        {
            //datagridBase.Rows.Remove(drv);
        }
        
        /// <summary>
        /// Clears the grid content
        /// </summary>
        public void Clean()
        {
            DataTable _DataTable = (DataTable)datagridBase.DataSource;
            _DataTable.Rows.Clear();

        }

        #endregion

        #region Virtual Methods

        protected virtual void AfterOpenMenu()
        {

        }
        protected virtual void ValidateCell(DataGridViewCell cellToValidate)
        {
        }

        #endregion

        private void datagridBase_RowValidating(object sender, DataGridViewCellCancelEventArgs e)
        {
            ValidateCell(datagridBase[e.ColumnIndex,e.RowIndex]);
        }

        private void datagridBase_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            datagridBase[e.ColumnIndex,e.RowIndex].ErrorText = string.Empty;
        }

        private void datagridBase_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            if(ActivateCellChangedEvent(datagridBase[e.ColumnIndex,e.RowIndex]))
                OnCellChanged(sender, new GridBaseEventArgs(getSelectedId(), datagridBase.SelectedRows[0]));
        }

        protected virtual bool ActivateCellChangedEvent(DataGridViewCell dataGridViewCell)
        {
            return true;
        }

        private void datagridBase_DataError(object sender, DataGridViewDataErrorEventArgs e)
        {

        }

        private void datagridBase_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                if (datagridBase.Columns[e.ColumnIndex] is DataGridViewLinkColumn)
                {
                    OnClickLinkCell(this, new GridBaseEventArgs(getSelectedId(), datagridBase.SelectedRows[0]));
                }
            }
            catch(Exception ex)
            {

            }

            


        }

        public virtual string ExportToExcel(FileInfo savedFile)
        {
            ExportToExcelHelper helperExcel = new ExportToExcelHelper(savedFile);
            helperExcel.AddRow();
            foreach (DataGridViewColumn h in  datagridBase.Columns)
            {
                helperExcel.WriteHeader(h.HeaderText);
            }
            foreach (DataGridViewRow n in datagridBase.Rows)
            {
                helperExcel.AddRow();
                foreach (DataGridViewCell c in n.Cells)
                {
                    helperExcel.WriteCell(c.Value.ToString());
                }
            }
            helperExcel.Close();
            return savedFile.FullName;
        }

    }
}
